/*
 * @Author: 0x9DEFA478
 * @Date: 2025-06-27 23:01:51
 * @LastEditTime: 2025-09-15 22:28:22
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * 
 */
#include "HMakeValue.hpp"
#include <sstream>


namespace HMake{

  Value::Value()noexcept:isConst(false),type(Type::None){}

  Value::~Value()noexcept{}


  Value::Value(const Value& value)noexcept{
    isConst=false;
    type=value.type;
    this->value=value.value.Clone();
  }

  Value::Value(Value&& value)noexcept{
    isConst=false;
    type=value.type;
    this->value=value.value;
    value.value=ValueArray_t();
  }
  

  Value& Value::operator=(const Value& value){
    if(isConst){
      throw std::runtime_error("无法对常量进行赋值");
    }
    if(value.type==Type::None){
      type=Type::None;
      this->value=ValueArray_t();
      return *this;
    }
    if((type!=Type::None)&&(type!=value.type)){
      throw std::runtime_error(std::string()+"无法将\""+TypeToString(value.type)+"\"类型转换为\""+TypeToString(type)+"\"类型");
    }
    type=value.type;
    this->value=value.value.Clone();
    return *this;
  }

  Value& Value::operator=(const std::string& value){
    if(isConst){
      throw std::runtime_error("无法对常量进行赋值");
    }
    if((type!=Type::None)&&(type!=Type::Single)){
      throw std::runtime_error(std::string()+"无法将\""+TypeToString(Type::Single)+"\"类型转换为\""+TypeToString(type)+"\"类型");
    }
    type=Type::Single;
    this->value=ValueArray_t::Array(1);
    this->value[0]=value;
    return *this;
  }

  Value& Value::operator=(const std::vector<std::string>& value){
    if(isConst){
      throw std::runtime_error("无法对常量进行赋值");
    }
    if((type!=Type::None)&&(type!=Type::Array)){
      throw std::runtime_error(std::string()+"无法将\""+TypeToString(Type::Array)+"\"类型转换为\""+TypeToString(type)+"\"类型");
    }
    if(value.size()<1){
      type=Type::None;
      this->value=ValueArray_t();
      return *this;
    }
    type=Type::Array;

    this->value=ValueArray_t::Array(value.size());
    for(std::size_t i=0,length=value.size();i<length;i++){
      this->value[i]=value[i];
    }
    return *this;
  }

  Value& Value::operator+=(const Value& value){
    if(isConst){
      throw std::runtime_error("无法对常量进行赋值");
    }
    if(value.type==Type::None){
      return *this;
    }
    if(type==Type::None){
      return operator=(value);
    }

    if(type==Type::Single){
      if(value.type==Type::Single){
        this->value[0]+=value.value[0];
      }else{
        std::stringstream ss;
  
        ss<<this->value[0];

        for(H::usize i=0,length=value.value.Length();i<length;i++){
          const auto& s=value.value[i];
          if(s.length()>0){
            ss<<s;
          }
        }

        this->value[0]=ss.str();
      }

      return *this;
    }

    if(type==Type::Array){
      H::usize addLen;

      if(value.type==Type::Single){
        addLen=1;
      }else{
        addLen=value.value.Length();
      }

      const auto old=this->value;
      auto oldLen=old.Length();

      this->value=ValueArray_t::Array(old.Length()+addLen);
      for(H::usize i=0;i<oldLen;i++){
        this->value[i]=old[i];
      }
      for(H::usize i=0;i<addLen;i++){
        this->value[oldLen+i]=value.value[i];
      }

      return *this;
    }
    
    throw std::runtime_error("被加值为不支持的类型");
  }

  Value Value::operator+(const Value& value)const{
    if(value.type==Type::None){
      return *this;
    }
    if(type==Type::None){
      return value;
    }

    if(type==Type::Single){
      Value r;

      r.type=type;
      r.value=ValueArray_t::Array(1);
      if(value.type==Type::Single){
        r.value[0]=this->value[0]+value.value[0];
      }else{
        std::stringstream ss;
   
        ss<<this->value[0];

        for(H::usize i=0,length=value.value.Length();i<length;i++){
          const auto& s=value.value[i];
          if(s.length()>0){
            ss<<s;
          }
        }
        r.value[0]=ss.str();
      }

      return r;
    }

    if(type==Type::Array){
      Value r;
      H::usize addLen;

      r.type=type;

      if(value.type==Type::Single){
        addLen=1;
      }else{
        addLen=value.value.Length();
      }

      auto oldLen=this->value.Length();

      r.value=ValueArray_t::Array(oldLen+addLen);
      for(H::usize i=0;i<oldLen;i++){
        r.value[i]=this->value[i];
      }
      for(H::usize i=0;i<addLen;i++){
        r.value[oldLen+i]=value.value[i];
      }

      return r;
    }
    
    throw std::runtime_error("被加值为不支持的类型");
  }

  Value& Value::operator-=(const Value& value){
    if(isConst){
      throw std::runtime_error("无法对常量进行赋值");
    }
    if(type==Type::None){
      return *this;
    }
    if(type!=Type::Array){
      throw std::runtime_error(std::string() + "\""+TypeToString(type)+"\"类型不支持\"-=\"运算");
    }

    std::vector<std::string> sArray;

    sArray.reserve(this->value.Length());

    for(H::usize i=0,length=this->value.Length();i<length;i++){
      const auto& s=this->value[i];
      bool isAdd=true;
      for(H::usize i=0,length=value.value.Length();i<length;i++){
        if(s==value.value[i]){
          isAdd=false;
          break;
        }
      }
      if(isAdd){
        sArray.emplace_back(s);
      }
    }

    this->value=ValueArray_t::Array(sArray.size());
    for(std::size_t i=0,length=sArray.size();i<length;i++){
      this->value[i]=sArray[i];
    }

    return *this;
  }

  Value Value::operator-(const Value& value)const{
    if(type==Type::None){
      return *this;
    }
    if(type!=Type::Array){
      throw std::runtime_error(std::string() + "\""+TypeToString(type)+"\"类型不支持\"-\"运算");
    }

    Value r;
    std::vector<std::string> sArray;

    r.type=Type::Array;

    sArray.reserve(this->value.Length());

    for(H::usize i=0,length=this->value.Length();i<length;i++){
      const auto& s=this->value[i];
      bool isAdd=true;
      for(H::usize i=0,length=value.value.Length();i<length;i++){
        if(s==value.value[i]){
          isAdd=false;
          break;
        }
      }
      if(isAdd){
        sArray.emplace_back(s);
      }
    }

    r.value=ValueArray_t::Array(sArray.size());
    for(std::size_t i=0,length=sArray.size();i<length;i++){
      r.value[i]=sArray[i];
    }

    return r;
  }

  bool Value::operator==(const Value& value)const{
    if(this==&value){
      return true;
    }

    if(type!=value.type){
      return false;
    }

    auto Length=this->value.Length();
    if(Length!=value.value.Length()){
      return false;
    }

    for(H::usize i=0;i<Length;i++){
      if(this->value[i]!=value.value[i]){
        return false;
      }
    }

    return true;
  }

  Value Value::ToArray()const{
    Value r(*this);

    if(!r.IsArray()){
      r.type=Type::Array;
    }
    return r;
  }

  std::string Value::String()const{
    std::stringstream ss;

    switch(type){
      case Type::Single:
        ss<<"\""<<value[0]<<"\"";
        break;
      case Type::Array:
        ss<<"[";
        for(H::usize i=0,length=value.Length();i<length;i++){
          if(i>0){
            ss<<":";
          }
          ss<<"\""<<value[i]<<"\"";
        }
        ss<<"]";
        break;
      case Type::None:
        ss<<"<None>";
        break;
      default:
        ss<<"<unknow type>";
        break;
    }

    return ss.str();
  }

  bool Value::bool_Value(const Value* value)noexcept{
    if((value==nullptr)||(value->IsNone())){
      return false;
    }
    auto arg0_arr=value->ValueArray();
    bool IsTrue=false;
    for(auto& Item:arg0_arr){
      if(Item.length()>0){
        IsTrue=true;
        break;
      }
    }
    return IsTrue;
  }

  const char* Value::TypeToString(Type type){
    switch(type){
      case Type::None:
        return "无类型";
      case Type::Single:
        return "单元素";
      case Type::Array:
        return "队列";
      default:
        break;
    }

    return "未知类型";
  }
  
}

